home *** CD-ROM | disk | FTP | other *** search
/ Revista do CD-ROM 97 / CD-ROM 97 / CD-ROM 97.iso / internet / ghostzilla / ghsetup.exe / chrome / comm.jar / content / editor / EditorPublish.js < prev    next >
Encoding:
JavaScript  |  2002-04-09  |  18.1 KB  |  616 lines

  1. /*
  2.  * The contents of this file are subject to the Netscape Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/NPL/
  6.  *
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  *
  12.  * The Original Code is Mozilla Communicator client code, released
  13.  * March 31, 1998.
  14.  *
  15.  * The Initial Developer of the Original Code is Netscape
  16.  * Communications Corporation. Portions created by Netscape are
  17.  * Copyright (C) 2001 Netscape Communications Corporation. All
  18.  * Rights Reserved.
  19.  *
  20.  * Contributor(s):
  21.  */
  22.  
  23. var gPublishPanel = 0;
  24. var gSettingsPanel = 1;
  25. var gCurrentPanel = gPublishPanel;
  26. var gPublishSiteData;
  27. var gReturnData;
  28. var gDefaultSiteIndex = -1;
  29. var gDefaultSiteName;
  30. var gPreviousDefaultSite;
  31. var gPreviousDefaultDir;
  32. var gPreviousTitle;
  33. var gSettingsChanged = false;
  34. var gInitialSiteName;
  35. var gInitialSiteIndex = -1;
  36.  
  37. // Dialog initialization code
  38. function Startup()
  39. {
  40.   window.opener.ok = false;
  41.  
  42.   if (!InitEditorShell()) return;
  43.  
  44.   // Element to edit is passed in
  45.   gInitialSiteName = window.arguments[1];
  46.   gReturnData = window.arguments[2];
  47.   if (!gReturnData)
  48.   {
  49.     dump("Publish: Return data object not supplied\n");
  50.     window.close();
  51.     return;
  52.   }
  53.  
  54.   gDialog.TabPanels           = document.getElementById("TabPanels");
  55.   gDialog.PublishTab          = document.getElementById("PublishTab");
  56.   gDialog.SettingsTab         = document.getElementById("SettingsTab");
  57.  
  58.   // Publish panel
  59.   gDialog.PageTitleInput      = document.getElementById("PageTitleInput");
  60.   gDialog.FilenameInput       = document.getElementById("FilenameInput");
  61.   gDialog.SiteList            = document.getElementById("SiteList");
  62.   gDialog.DocDirList          = document.getElementById("DocDirList");
  63.   gDialog.OtherDirCheckbox    = document.getElementById("OtherDirCheckbox");
  64.   gDialog.OtherDirRadiogroup  = document.getElementById("OtherDirRadiogroup");
  65.   gDialog.SameLocationRadio   = document.getElementById("SameLocationRadio");
  66.   gDialog.UseSubdirRadio      = document.getElementById("UseSubdirRadio");
  67.   gDialog.OtherDirList        = document.getElementById("OtherDirList");
  68.  
  69.   // Settings Panel
  70.   gDialog.SettingsPanel       = document.getElementById("SettingsPanel");
  71.   gDialog.SiteNameInput       = document.getElementById("SiteNameInput");
  72.   gDialog.PublishUrlInput     = document.getElementById("PublishUrlInput");
  73.   gDialog.BrowseUrlInput      = document.getElementById("BrowseUrlInput");
  74.   gDialog.UsernameInput       = document.getElementById("UsernameInput");
  75.   gDialog.PasswordInput       = document.getElementById("PasswordInput");
  76.   gDialog.SavePassword        = document.getElementById("SavePassword");
  77.  
  78.   gDialog.PublishButton       = document.documentElement.getButton("accept");
  79.  
  80.   // Change 'Ok' button to 'Publish'
  81.   gDialog.PublishButton.setAttribute("label", GetString("Publish"));
  82.   
  83.   gPublishSiteData = GetPublishSiteData();
  84.   gDefaultSiteName = GetDefaultPublishSiteName();
  85.   gPreviousDefaultSite = gDefaultSiteName;
  86.  
  87.   var addNewSite = false;
  88.   if (gPublishSiteData)
  89.   {
  90.     FillSiteList();
  91.   }
  92.   else
  93.   {
  94.     // No current site data, start a new item in the Settings panel
  95.     AddNewSite();
  96.     addNewSite = true;
  97.   }
  98.  
  99.   var docUrl = GetDocumentUrl();
  100.   var scheme = GetScheme(docUrl);
  101.   var filename = "";
  102.  
  103.   if (scheme)
  104.   {
  105.     filename = GetFilename(docUrl);
  106.  
  107.     if (scheme != "file")
  108.     {
  109.       var siteFound = false;
  110.  
  111.       // Editing a remote URL.
  112.       // Attempt to find doc URL in Site Data
  113.       if (gPublishSiteData)
  114.       {
  115.         var dirObj = {};
  116.         var siteIndex = FindSiteIndexAndDocDir(gPublishSiteData, docUrl, dirObj);
  117.         
  118.         // Select this site only if the same as user's intended site, or there wasn't one
  119.         if (siteIndex != -1 && (gInitialSiteIndex == -1 || siteIndex == gInitialSiteIndex))
  120.         {
  121.           siteFound = true;
  122.  
  123.           // Select the site we found
  124.           gDialog.SiteList.selectedIndex = siteIndex;
  125.           var docDir = dirObj.value;
  126.  
  127.           // Use the directory within site in the editable menulist
  128.           gPublishSiteData[siteIndex].docDir = docDir;
  129.  
  130.           //XXX HOW DO WE DECIDE WHAT "OTHER" DIR TO USE?
  131.           //gPublishSiteData[siteIndex].otherDir = docDir;
  132.         }
  133.       }
  134.       if (!siteFound)
  135.       {
  136.         // Not found in site database 
  137.         // Setup for a new site and use data from a remote URL
  138.         if (!addNewSite)
  139.           AddNewSite();
  140.  
  141.         addNewSite = true;
  142.  
  143.         var publishData = CreatePublishDataFromUrl(docUrl);
  144.         if (publishData)
  145.         {
  146.           filename = publishData.filename;
  147.           gDialog.SiteNameInput.value    = publishData.siteName;
  148.           gDialog.PublishUrlInput.value  = publishData.publishUrl;
  149.           gDialog.BrowseUrlInput.value   = publishData.browseUrl;
  150.           gDialog.UsernameInput.value    = publishData.username;
  151.           gDialog.PasswordInput.value    = publishData.password;
  152.           gDialog.SavePassword.checked   = false;
  153.         }
  154.       }
  155.     }
  156.   }
  157.   try {
  158.     gPreviousTitle = editorShell.GetDocumentTitle();
  159.   } catch (e) {}
  160.  
  161.   gDialog.PageTitleInput.value = gPreviousTitle;
  162.   gDialog.FilenameInput.value = filename;
  163.   
  164.   if (!addNewSite)
  165.   {
  166.     // If not adding a site and we haven't selected a site -- use initial or default site
  167.     if (gDialog.SiteList.selectedIndex == -1)
  168.       gDialog.SiteList.selectedIndex = (gInitialSiteIndex != -1) ? gInitialSiteIndex : gDefaultSiteIndex;
  169.  
  170.     // Fill in  all the site data for currently-selected site
  171.     SelectSiteList();
  172.     SetTextboxFocus(gDialog.PageTitleInput);
  173.   }
  174.  
  175.   if (gDialog.SiteList.selectedIndex == -1)
  176.   {
  177.     // No selected site -- assume same directory
  178.     gDialog.OtherDirRadiogroup.selectedItem = gDialog.SameLocationRadio;
  179.   }
  180.   else if (gPublishSiteData[gDialog.SiteList.selectedIndex].docDir == 
  181.         gPublishSiteData[gDialog.SiteList.selectedIndex].otherDir)
  182.   {
  183.     // For now, check "same location" if dirs are already set to same directory
  184.     gDialog.OtherDirRadiogroup.selectedItem = gDialog.SameLocationRadio;
  185.   }
  186.   else
  187.   {
  188.     gDialog.OtherDirRadiogroup.selectedItem = gDialog.UseSubdirRadio;
  189.   }
  190.  
  191.   doEnabling();
  192.  
  193.   SetWindowLocation();
  194. }
  195.  
  196. function FillSiteList()
  197. {
  198.   ClearMenulist(gDialog.SiteList);
  199.   gDefaultSiteIndex = -1;
  200.  
  201.   // Fill the site lists
  202.   var count = gPublishSiteData.length;
  203.   var i;
  204.  
  205.   for (i = 0; i < count; i++)
  206.   {
  207.     var name = gPublishSiteData[i].siteName;
  208.     // XXX Bug 131481: Using "max-width" style and "crop" attribute 
  209.     //     don't constrain grid width properly, resulting in cut-off buttons
  210.     //     We'll truncate label strings to prevent this problem
  211.     var menuitem = AppendLabelAndValueToMenulist(gDialog.SiteList, 
  212.                         TruncateStringAtWordEnd(name, 30, true), name);
  213.     // Highlight the default site
  214.     if (name == gDefaultSiteName)
  215.     {
  216.       gDefaultSiteIndex = i;
  217.       if (menuitem)
  218.       {
  219.         menuitem.setAttribute("class", "menuitem-highlight-1");
  220.         menuitem.setAttribute("default", "true");
  221.       }
  222.     }
  223.     // Find initial site location
  224.     if (name == gInitialSiteName)
  225.       gInitialSiteIndex = i;
  226.   }
  227. }
  228.  
  229. function doEnabling()
  230. {
  231.   var disableOther = !gDialog.OtherDirCheckbox.checked;
  232.   gDialog.SameLocationRadio.disabled = disableOther;
  233.   gDialog.UseSubdirRadio.disabled = disableOther;
  234.   gDialog.OtherDirList.disabled = (disableOther || gDialog.SameLocationRadio.selected);
  235. }
  236.  
  237. function SelectSiteList()
  238. {
  239.   var selectedSiteIndex = gDialog.SiteList.selectedIndex;  
  240.  
  241.   var siteName = "";
  242.   var publishUrl = "";
  243.   var browseUrl = "";
  244.   var username = "";
  245.   var password = "";
  246.   var savePassword = false;
  247.   var publishOtherFiles = true;
  248.  
  249.   ClearMenulist(gDialog.DocDirList);
  250.   ClearMenulist(gDialog.OtherDirList);
  251.  
  252.   if (gPublishSiteData && selectedSiteIndex != -1)
  253.   {
  254.     siteName = gPublishSiteData[selectedSiteIndex].siteName;
  255.     publishUrl = gPublishSiteData[selectedSiteIndex].publishUrl;
  256.     browseUrl = gPublishSiteData[selectedSiteIndex].browseUrl;
  257.     username = gPublishSiteData[selectedSiteIndex].username;
  258.     savePassword = gPublishSiteData[selectedSiteIndex].savePassword;
  259.     if (savePassword)
  260.       password = gPublishSiteData[selectedSiteIndex].password;
  261.  
  262.     // Fill the directory menulists
  263.     if (gPublishSiteData[selectedSiteIndex].dirList.length)
  264.     {
  265.       for (var i = 0; i < gPublishSiteData[selectedSiteIndex].dirList.length; i++)
  266.       {
  267.         AppendStringToMenulist(gDialog.DocDirList, gPublishSiteData[selectedSiteIndex].dirList[i]);
  268.         AppendStringToMenulist(gDialog.OtherDirList, gPublishSiteData[selectedSiteIndex].dirList[i]);
  269.       }
  270.     }
  271.     gDialog.DocDirList.value = gPublishSiteData[selectedSiteIndex].docDir;
  272.     gDialog.OtherDirList.value = gPublishSiteData[selectedSiteIndex].otherDir;
  273.  
  274.     gDialog.DocDirList.value = FormatDirForPublishing(gPublishSiteData[selectedSiteIndex].docDir);
  275.     gDialog.OtherDirList.value = FormatDirForPublishing(gPublishSiteData[selectedSiteIndex].otherDir);
  276.     publishOtherFiles = gPublishSiteData[selectedSiteIndex].publishOtherFiles;
  277.  
  278.   }
  279.   else
  280.   {
  281.     gDialog.DocDirList.value = "";
  282.     gDialog.OtherDirList.value = "";
  283.   }
  284.  
  285.   gDialog.SiteNameInput.value    = siteName;
  286.   gDialog.PublishUrlInput.value  = publishUrl;
  287.   gDialog.BrowseUrlInput.value   = browseUrl;
  288.   gDialog.UsernameInput.value    = username;
  289.   gDialog.PasswordInput.value    = password;
  290.   gDialog.SavePassword.checked   = savePassword;
  291.   gDialog.OtherDirCheckbox.checked = publishOtherFiles;
  292.  
  293.   doEnabling();
  294. }
  295.  
  296. function AddNewSite()
  297. {
  298.   // Button in Publish panel allows user
  299.   //  to automatically switch to "Settings" panel
  300.   //  to enter data for new site
  301.   SwitchPanel(gSettingsPanel);
  302.   
  303.   gDialog.SiteList.selectedIndex = -1;
  304.  
  305.   SelectSiteList();
  306.   
  307.   gSettingsChanged = true;
  308.  
  309.   SetTextboxFocus(gDialog.SiteNameInput);
  310. }
  311.  
  312. function SelectPublishTab()
  313. {
  314.   if (gSettingsChanged)
  315.   {
  316.     gCurrentPanel = gPublishPanel;
  317.     if (!ValidateSettings())
  318.       return;
  319.  
  320.     gCurrentPanel = gSettingsPanel;
  321.   }
  322.  
  323.   SwitchPanel(gPublishPanel);
  324.   SetTextboxFocus(gDialog.PageTitleInput);
  325. }
  326.  
  327. function SelectSettingsTab()
  328. {
  329.   SwitchPanel(gSettingsPanel);
  330.   SetTextboxFocus(gDialog.SiteNameInput);
  331. }
  332.  
  333. function SwitchPanel(panel)
  334. {
  335.   if (gCurrentPanel != panel)
  336.   {
  337.     // Set index for starting panel on the <tabpanels> element
  338.     gDialog.TabPanels.selectedIndex = panel;
  339.     if (panel == gSettingsPanel)
  340.     {
  341.       // Trigger setting of style for the tab widgets
  342.       gDialog.SettingsTab.selected = "true";
  343.       gDialog.PublishTab.selected = null;
  344.     } else {
  345.       gDialog.PublishTab.selected = "true";
  346.       gDialog.SettingsTab.selected = null;
  347.     }
  348.     gCurrentPanel = panel;
  349.  
  350.     // XXX Another hack to workaround bug 131481
  351.     // Resize dialog to be sure buttons are not cut off the right
  352.     window.sizeToContent();
  353.   }
  354. }
  355.  
  356. function onInputSettings()
  357. {
  358.   // TODO: Save current data during SelectSite and compare here
  359.   //       to detect if real change has occured?
  360.   gSettingsChanged = true;
  361. }
  362.  
  363. function GetPublishUrlInput()
  364. {
  365.   gDialog.PublishUrlInput.value = FormatUrlForPublishing(gDialog.PublishUrlInput.value);
  366.   return gDialog.PublishUrlInput.value;
  367. }
  368.  
  369. function GetBrowseUrlInput()
  370. {
  371.   gDialog.BrowseUrlInput.value = FormatUrlForPublishing(gDialog.BrowseUrlInput.value);
  372.   return gDialog.BrowseUrlInput.value;
  373. }
  374.  
  375. function GetDocDirInput()
  376. {
  377.   gDialog.DocDirList.value = FormatDirForPublishing(gDialog.DocDirList.value);
  378.   return gDialog.DocDirList.value;
  379. }
  380.  
  381. function GetOtherDirInput()
  382. {
  383.   gDialog.OtherDirList.value = FormatDirForPublishing(gDialog.OtherDirList.value);
  384.   return gDialog.OtherDirList.value;
  385. }
  386.  
  387. function ChooseDir(menulist)
  388. {
  389.   //TODO: For FTP publish destinations, get file listing of just dirs 
  390.   //  and build a tree to let user select dir
  391. }
  392.  
  393. function ValidateSettings()
  394. {
  395.   var siteName = TrimString(gDialog.SiteNameInput.value);
  396.   if (!siteName)
  397.   {
  398.     ShowErrorInPanel(gSettingsPanel, "MissingSiteNameError", gDialog.SiteNameInput);
  399.     return false;
  400.   }
  401.   if (PublishSiteNameExists(siteName, gPublishSiteData, gDialog.SiteList.selectedIndex))
  402.   {
  403.     SwitchPanel(gSettingsPanel);
  404.     ShowInputErrorMessage(GetString("DuplicateSiteNameError").replace(/%name%/, siteName));            
  405.     SetTextboxFocus(gDialog.SiteNameInput);
  406.     return false;
  407.   }
  408.  
  409.   // Extract username and password while removing them from publishingUrl
  410.   var urlUserObj = {};
  411.   var urlPassObj = {};
  412.   var publishUrl = StripUsernamePassword(gDialog.PublishUrlInput.value, urlUserObj, urlPassObj);
  413.   if (publishUrl)
  414.   {
  415.     publishUrl = FormatUrlForPublishing(publishUrl);
  416.     gDialog.PublishUrlInput.value = publishUrl;
  417.   }
  418.   else
  419.   {
  420.     ShowErrorInPanel(gSettingsPanel, "MissingPublishUrlError", gDialog.PublishUrlInput);
  421.     return false;
  422.   }
  423.  
  424.   var browseUrl = GetBrowseUrlInput();
  425.  
  426.   var username = TrimString(gDialog.UsernameInput.value);
  427.   var savePassword = gDialog.SavePassword.checked;
  428.   var password = gDialog.PasswordInput.value;
  429.   var publishOtherFiles = gDialog.OtherDirCheckbox.checked;
  430.   
  431.   //XXX If there was a username and/or password in the publishUrl 
  432.   //    AND in the input field, which do we use?
  433.   //    Let's use those in url only if input is empty 
  434.   if (!username)
  435.   {
  436.     username = urlUserObj.value;
  437.     gDialog.UsernameInput.value = username;
  438.     gSettingsChanged = true;
  439.   }
  440.   if (!password)
  441.   {
  442.     password = urlPassObj.value;
  443.     gDialog.PasswordInput.value = password;
  444.     gSettingsChanged = true;
  445.   }
  446.  
  447.   // Update or add data for a site 
  448.   var siteIndex = gDialog.SiteList.selectedIndex;
  449.   var newSite = false;
  450.  
  451.   if (siteIndex == -1)
  452.   {
  453.     // No site is selected, add a new site at the end
  454.     if (gPublishSiteData)
  455.     {
  456.       siteIndex = gPublishSiteData.length;
  457.     }
  458.     else
  459.     {
  460.       // First time: start entire site array
  461.       gPublishSiteData = new Array(1);
  462.       siteIndex = 0;
  463.       gDefaultSiteIndex = 0;
  464.       gDefaultSiteName = siteName;
  465.     }    
  466.     gPublishSiteData[siteIndex] = {};
  467.     gPublishSiteData[siteIndex].docDir = "";
  468.     gPublishSiteData[siteIndex].otherDir = "";
  469.     gPublishSiteData[siteIndex].dirList = [""];
  470.     gPublishSiteData[siteIndex].publishOtherFiles = true;
  471.     newSite = true;
  472.   }
  473.   gPublishSiteData[siteIndex].siteName = siteName;
  474.   gPublishSiteData[siteIndex].publishUrl = publishUrl;
  475.   gPublishSiteData[siteIndex].browseUrl = browseUrl;
  476.   gPublishSiteData[siteIndex].username = username;
  477.   // Don't save password in data that will be saved in prefs
  478.   gPublishSiteData[siteIndex].password = savePassword ? password : "";
  479.   gPublishSiteData[siteIndex].savePassword = savePassword;
  480.  
  481.   if (publishOtherFiles != gPublishSiteData[siteIndex].publishOtherFiles)
  482.     gSettingsChanged = true;
  483.  
  484.   gPublishSiteData[siteIndex].publishOtherFiles = publishOtherFiles;
  485.  
  486.   gDialog.SiteList.selectedIndex = siteIndex;
  487.   if (siteIndex == gDefaultSiteIndex)
  488.     gDefaultSiteName = siteName;
  489.  
  490.   // Should never be empty, but be sure we have a default site
  491.   if (!gDefaultSiteName)
  492.   {
  493.     gDefaultSiteName = gPublishSiteData[0].siteName;
  494.     gDefaultSiteIndex = 0;
  495.   }
  496.  
  497.   // Rebuild the site menulist if we added a new site
  498.   if (newSite)
  499.   {
  500.     FillSiteList();
  501.     gDialog.SiteList.selectedIndex = siteIndex;
  502.   }
  503.   else
  504.   {
  505.     // Update selected item if sitename changed 
  506.     var selectedItem = gDialog.SiteList.selectedItem;
  507.     if (selectedItem && selectedItem.getAttribute("label") != siteName)
  508.     {
  509.       // XXX More hacks to workaround bug 131481
  510.       // The real sitename
  511.       selectedItem.setAttribute("value", siteName);
  512.  
  513.       // Truncate string to show in the menulist
  514.       var truncatedName = TruncateStringAtWordEnd(siteName, 30, true);
  515.       selectedItem.setAttribute("label", truncatedName);
  516.       gDialog.SiteList.setAttribute("label", truncatedName);
  517.     }
  518.   }
  519.   
  520.   // Get the directory name in site to publish to
  521.   var docDir = GetDocDirInput();
  522.  
  523.   gPublishSiteData[siteIndex].docDir = docDir;
  524.  
  525.   // And directory for images and other files
  526.   var otherDir = GetOtherDirInput();
  527.   if (gDialog.SameLocationRadio.selected)
  528.     otherDir = docDir;
  529.   else
  530.     otherDir = GetOtherDirInput();
  531.  
  532.   gPublishSiteData[siteIndex].otherDir = otherDir;
  533.  
  534.   // Fill return data object
  535.   gReturnData.siteName = siteName;
  536.   gReturnData.publishUrl = publishUrl;
  537.   gReturnData.browseUrl = browseUrl;
  538.   gReturnData.username = username;
  539.   // Note that we use the password for the next publish action 
  540.   // even if savePassword is false; but we won't save it in PasswordManager database
  541.   gReturnData.password = password;
  542.   gReturnData.savePassword = savePassword;
  543.   gReturnData.docDir = gPublishSiteData[siteIndex].docDir;
  544.   gReturnData.otherDir = gPublishSiteData[siteIndex].otherDir;
  545.   gReturnData.publishOtherFiles = publishOtherFiles;
  546.   gReturnData.dirList = gPublishSiteData[siteIndex].dirList;
  547.   return true;
  548. }
  549.  
  550. function ValidateData()
  551. {
  552.   if (!ValidateSettings())
  553.     return false;
  554.  
  555.   var siteIndex = gDialog.SiteList.selectedIndex;
  556.   if (siteIndex == -1)
  557.     return false;
  558.  
  559.   var filename = TrimString(gDialog.FilenameInput.value);
  560.   if (!filename)
  561.   {
  562.     ShowErrorInPanel(gPublishPanel, "MissingPublishFilename", gDialog.FilenameInput);
  563.     return false;
  564.   }
  565.   gReturnData.filename = filename;
  566.  
  567.   return true;
  568. }
  569.  
  570. function ShowErrorInPanel(panelId, errorMsgId, widgetWithError)
  571. {
  572.   SwitchPanel(panelId);
  573.   ShowInputErrorMessage(GetString(errorMsgId));
  574.   if (widgetWithError)
  575.     SetTextboxFocus(widgetWithError);
  576. }
  577.  
  578. function doHelpButton()
  579. {
  580.   if (gCurrentPanel == gPublishPanel)
  581.     openHelp("comp-doc-publish-publishtab");
  582.   else
  583.     openHelp("comp-doc-publish-settingstab");
  584. }
  585.  
  586. function onAccept()
  587. {
  588.   if (ValidateData())
  589.   {
  590.     //  DON'T save the docDir and otherDir before trying to publish
  591.     gReturnData.saveDirs = false;
  592.  
  593.     // We save new site data to prefs only if we are attempting to publish
  594.     if (gSettingsChanged)
  595.       SavePublishDataToPrefs(gReturnData);
  596.  
  597.     // Set flag to resave data after publishing
  598.     // so we save docDir and otherDir if we published successfully
  599.     gReturnData.savePublishData = true;
  600.  
  601.     var title = TrimString(gDialog.PageTitleInput.value);
  602.     if (title != gPreviousTitle)
  603.     {
  604.       try {
  605.         editorShell.SetDocumentTitle(title);
  606.       } catch (e) {}
  607.     }
  608.  
  609.     SaveWindowLocation();
  610.     window.opener.ok = true;
  611.     return true;
  612.   }
  613.  
  614.   return false;
  615. }
  616.